package com.ifgi.sitcom.campusmapperNDrawer.io;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;

import org.apache.xerces.impl.dv.util.Base64;
import com.gamificationlibrary.model.*;
import com.gamificationlibrary.model.Score;
import com.ifgi.sitcom.campusmapperNDrawer.exceptions.UploadException;
import com.ifgi.sitcom.campusmapperNDrawer.gamedata.PlayerAdapter;

import android.util.Log;

/*
 * upload of sparql/ rdf data to lodum triple store
 */
public class RDFUpload {

	/************* server path ****************/
	private static final String UPLOAD_SERVER_URI = "http://data.uni-muenster.de:8080/openrdf-workbench/repositories/indoormapping/update";
	
	private static final String CONTEXT_URI = "<http://data.uni-muenster.de/context/indoormapping>";

	public void uploadRDF(String rdfString) throws UploadException{

		String updateScript =
				"PREFIX rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#> " +
				"PREFIX foaf:<http://xmlns.com/foaf/0.1/> " +
				"PREFIX prv: <http://purl.org/net/provenance/ns/> " +
				"PREFIX indoor:<http://data.uni-muenster.de/context/indoormapping/>	" + 
				"INSERT DATA { GRAPH " + CONTEXT_URI + " { " + rdfString +"} }";
		Log.v("updateScript", updateScript);

		// Construct data
		String data = null;
		try {
			data = URLEncoder.encode("update", "UTF-8") + "="
					+ URLEncoder.encode(updateScript, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			throw new UploadException();
		}

		
		// Send data
		try {
			URL url = new URL(UPLOAD_SERVER_URI);
			URLConnection conn = url.openConnection();
			String userpass = "indoormapping:!nd00rmapping"; // username:password
			
					String basicAuth = "Basic " + new String(Base64.encode(userpass.getBytes()));
					conn.setRequestProperty ("Authorization", basicAuth);

			// Allow Outputs
			 conn.setDoOutput(true);
			OutputStreamWriter wr = new OutputStreamWriter(
					conn.getOutputStream());
			wr.write(data);
			wr.flush();

			// Get the response
			BufferedReader rd = new BufferedReader(new InputStreamReader(
					conn.getInputStream()));
			String line;
			while ((line = rd.readLine()) != null) {
				Log.v("response", line);
			}
			
			// close streams
			wr.close();
			rd.close();
			
		} catch (IOException e) {
			e.printStackTrace();
			throw new UploadException();
		}
	}
	
	
	public void uploadePlayer(PlayerAdapter player)
	{
		String RDFRegisterInsert = 
				"<indoor:"+player.getEmail()+"> rdf:type prv:Player . "+
				"<indoor:"+player.getEmail()+"> indoor:hasIDPlus '"+player.getIDPlus()+"' . "+
				"<indoor:"+player.getEmail()+"> foaf:nick '" + player.getUsername() + "' . "+
				"<indoor:"+player.getEmail()+"> foaf:mbox '" + player.getEmail() + "' . "+ 
				"<indoor:"+player.getEmail()+"> indoor:hasRegistrationDate '" + player.getRegistrationDate() + "'^^xsd:dateTime . " +
				"<indoor:"+player.getEmail()+"> indoor:hasTotalPlayerScore '" + player.getScoreTotal().getValue() +"'^^xsd:integer . ";
			
		        try {
					this.uploadRDF(RDFRegisterInsert);			
				} catch (UploadException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}	
	}
	
	public void uploadScorePerFloorPlan(String email, String FloorURICode, int score, String date)
	{
		String scorePerPlanRDF = 
		"<indoor:"+ email + "> indoor:hasRelationToFloorPlan <indoor:"+ email + "/scorefloor" +date+"> . " +
		"<indoor:"+ email + "/scorefloor" +date+"> rdf:type prv:FloorScoreRelation .	" +	
		"<indoor:"+ email + "/scorefloor" +date+"> indoor:hasFloor <"+FloorURICode +"> . " +
		"<indoor:"+ email + "/scorefloor" +date+"> indoor:hasPlayerScore '" + score+ "'^^xsd:integer .	" +
		"<indoor:"+ email + "/scorefloor" +date+"> indoor:hasScoreDate '" + date + "'^^xsd:dateTime . " ;
		
			/*	"<indoor:serenamartella00@gmail.com> indoor:hasRelationToFloorPlan <indoor:serenamartella00@gmail.com/scorefloor" +date+"> . " +
				"<indoor:serenamartella00@gmail.com/scorefloor" +date+"> rdf:type prv:FloorScoreRelation .	" +	
				"<indoor:serenamartella00@gmail.com/scorefloor" +date+"> indoor:hasFloor <"+FloorURICode +"> . " +
				"<indoor:serenamartella00@gmail.com/scorefloor" +date+"> indoor:hasPlayerScore '" + score+ "'^^xsd:integer .	" +
				"<indoor:serenamartella00@gmail.com/scorefloor" +date+"> indoor:hasScoreDate '" + date + "'^^xsd:dateTime . " ;
		*/
		
		Log.v("urifloor",FloorURICode);
		Log.v("scoreFloor",scorePerPlanRDF);
		 try {
				this.uploadRDF(scorePerPlanRDF);			
			} catch (UploadException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}	
		
	}


}
